package com.glp.work.flow.controller;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.api.FlowableTaskAlreadyClaimedException;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.glp.common.enums.ReturnEnum;
import com.glp.common.reponse.BaseResult;
import com.glp.work.flow.client.WfProcessQueryClient;
import com.glp.work.flow.constant.APICode;
import com.glp.work.flow.constant.Constants;
import com.glp.work.flow.constant.Keys;
import com.glp.work.flow.constant.OrderStatus;
import com.glp.work.flow.exception.APIException;
import com.glp.work.flow.mapper.WfFormTimeConsumingMapper;
import com.glp.work.flow.pojo.WfFormExample;
import com.glp.work.flow.pojo.WfFormTimeConsuming;
import com.glp.work.flow.pojo.WfTaskAssignNode;
import com.glp.work.flow.request.BatchOrder;
import com.glp.work.flow.request.FlowTaskHistoryDTO;
import com.glp.work.flow.request.ToDoTasksRequest;
import com.glp.work.flow.request.WfOrderDetailQueryBySaDTO;
import com.glp.work.flow.request.WfOrderDetailQueryDTO;
import com.glp.work.flow.request.WfOrderDetailQueryDoneDTO;
import com.glp.work.flow.request.WfOrderDetailQueryToDoDTO;
import com.glp.work.flow.request.WfOrderQueryDTO;
import com.glp.work.flow.response.PageInfoResponse;
import com.glp.work.flow.response.ProcessResponse;
import com.glp.work.flow.response.ToDoTasksResponse;
import com.glp.work.flow.response.WfOrderResponse;
import com.glp.work.flow.response.WfOrderResultDTO;
import com.glp.work.flow.service.OrderInfoService;
import com.glp.work.flow.service.SyncProcessStatusService;
import com.glp.work.flow.service.UserService;
import com.glp.work.flow.service.WfBatchService;
import com.glp.work.flow.service.WfFormSnapshotService;
import com.glp.work.flow.service.WfPlatformDefModleService;
import com.glp.work.flow.service.WfProcessQueryService;
import com.glp.work.flow.utils.TraceIDUtils;
import com.glp.work.flow.utils.VersionUtils;
import com.glp.work.flow.workflow.plugin.flowable.constant.FlowConstant;
import com.glp.work.flow.workflow.plugin.flowable.util.DateUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import tk.mybatis.mapper.entity.Example;

/**
 * 流程查询Controller
 *
 * @author jhuang1
 */
@Api(tags = {"流程查询Controller"})
@Slf4j
@RequestMapping("/query")
@RestController
public class WfProcessQueryController implements WfProcessQueryClient {

    @Resource
    private WfProcessQueryService wfProcessQueryService;
    @Resource
    private WfBatchService wfBatchService;
    @Resource
    TaskService taskService;
    @Resource
    private UserService userService;
    @Resource
    private WfFormTimeConsumingMapper wfFormTimeConsumingMapper;
    @Resource
    private SyncProcessStatusService syncProcessStatusService;
    @Resource
    private WfFormSnapshotService wfFormSnapshotService;
    @Resource
    private OrderInfoService orderInfoService;

    @Resource
    private WfPlatformDefModleService wfPlatformDefModleService;


    /**
     * @MethodName: queryToDoTasks
     * @Description: 查询代办工单
     * @Param: [wfOrderQueryDTO]
     * @Return: com.glp.common.reponse.BaseResult<com.glp.work.flow.response.PageInfoResponse < com.glp.work.flow.response.WfOrderResultDTO>>
     * @Author: ywguo
     * @Date: 2020/6/9
     **/
    @PostMapping(value = "/client/queryToDoTasks", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "查询待办工单")
    @ResponseBody
    @Override
    public BaseResult<PageInfoResponse<WfOrderResultDTO>> queryToDoTasks(@RequestBody WfOrderQueryDTO wfOrderQueryDTO) {
        log.info("查询待办工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        verificationUserAndApp(wfOrderQueryDTO);
        List<String> list = userService.personRoles(wfOrderQueryDTO.getUserNo(), wfOrderQueryDTO.getAppId());
        log.info("用户对应的角色信息,请求参数:{}", list);
        wfOrderQueryDTO.setRoleCode(list);
        return toDoTasksExtraction(wfOrderQueryDTO);
    }

    /**
     * @MethodName: queryDoneTasks
     * @Description: 查询已办工单
     * @Param: [wfOrderQueryDTO]
     * @Return: com.glp.common.reponse.BaseResult<com.glp.work.flow.response.PageInfoResponse < com.glp.work.flow.response.WfOrderResultDTO>>
     * @Author: ywguo
     * @Date: 2020/6/9
     **/
    @PostMapping(value = "/client/queryDoneTasks", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "查询已办工单")
    @ResponseBody
    @Override
    public BaseResult<PageInfoResponse<WfOrderResultDTO>> queryDoneTasks(@RequestBody WfOrderQueryDTO wfOrderQueryDTO) {
        log.info("查询已办工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        if (StringUtils.isBlank(wfOrderQueryDTO.getUserNo())) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        if (StringUtils.isBlank(wfOrderQueryDTO.getAppId())) {
            throw new APIException(APICode.DATA_ERROR, "appId不能为空！");
        }
        return doneTasksExtraction(wfOrderQueryDTO);
    }

    @PostMapping(value = "/client/queryMyTasks", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "查询我的工单")
    @ResponseBody
    @Override
    public BaseResult<PageInfoResponse<WfOrderResultDTO>> queryMyOrder(@RequestBody WfOrderQueryDTO wfOrderQueryDTO) {
        log.info("查询我的工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        verificationUserAndApp(wfOrderQueryDTO);
        return queryToDoTasks(wfOrderQueryDTO.getUserNo(), wfOrderQueryDTO);
    }

    @PostMapping(value = "/client/queryMyApplicationOrder", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation(value = "查询我申请的工单")
    @ResponseBody
    @Override
    public BaseResult<PageInfoResponse<WfOrderResultDTO>> queryMyApplicationOrder(@RequestBody WfOrderQueryDTO wfOrderQueryDTO) {
        log.info("查询我申请的工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        verificationUserAndApp(wfOrderQueryDTO);
        return myApplication(wfOrderQueryDTO.getUserNo(), wfOrderQueryDTO);
    }

    private void verificationUserAndApp(WfOrderQueryDTO wfOrderQueryDTO) {
        if (StringUtils.isBlank(wfOrderQueryDTO.getUserNo())) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        if (StringUtils.isBlank(wfOrderQueryDTO.getAppId())) {
            throw new APIException(APICode.DATA_ERROR, "appId不能为空！");
        }
    }

    @ApiOperation(value = "待办任务数量统计查询")
    @PostMapping(value = "/client/totalToDoTasks", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @Override
    public BaseResult<List<ToDoTasksResponse>> totalToDoTasks(@RequestBody ToDoTasksRequest req) {
        log.info("待办任务数量统计查询:{}", req);
        if (StringUtils.isBlank(req.getUserNo())) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        List<ToDoTasksResponse> list = wfProcessQueryService.totalToDoTasks(req);
        BaseResult<List<ToDoTasksResponse>> result = new BaseResult<>(APICode.SUCCESS.getCode(), "待办任务数量统计查询", list);
        log.info("待办任务数量统计查询结果:{}", JSON.toJSONString(result));
        return result;
    }

    @ApiOperation(value = "待办任务数量统计查询Headers")
    @RequestMapping(value = "/client/totalToDoTasks/headers", method = RequestMethod.POST)
    @ResponseBody
    @Override
    public BaseResult<ToDoTasksResponse> querytotalToDoTasksHeaders(@RequestHeader(required = false) String appId, @RequestHeader String userNo) {
        log.info("待办任务数量统计查询:{}，{}", userNo, appId);
        if (StringUtils.isBlank(userNo)) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        ToDoTasksResponse toDoTasksResponse = wfProcessQueryService.querytotalToDoTasksHeaders(appId, userNo);
        BaseResult<ToDoTasksResponse> result = new BaseResult<>(APICode.SUCCESS.getCode(), "待办任务数量统计查询", toDoTasksResponse);
        log.info("待办任务数量统计查询结果:{}", JSON.toJSONString(result));
        return result;
    }

    @ApiOperation(value = "根据用户编号待办任务数量统计查询Headers")
    @RequestMapping(value = "/totalToDoTasksByUserNo/headers", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult<ToDoTasksResponse> querytotalToDoTasksHeaders(@RequestHeader String userNo) {
        log.info("根据用户编号查询待办任务数量统计查询:{}", userNo);
        if (StringUtils.isBlank(userNo)) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        ToDoTasksResponse toDoTasksResponse = wfProcessQueryService.querytotalToDoTasksHeaders(null, userNo);
        BaseResult<ToDoTasksResponse> result = new BaseResult<>(APICode.SUCCESS.getCode(), "待办任务数量统计查询", toDoTasksResponse);
        log.info("待办任务数量统计查询结果:{}", JSON.toJSONString(result));
        return result;
    }


    /**
     * 查询代办工单
     *
     * @param userNo 登入用户
     * @return 工单列表
     */
    @GetMapping(value = "/queryToDoTasks")
    @ApiOperation(value = "查询我的任务")
    @ResponseBody
    public BaseResult<PageInfoResponse<WfOrderResultDTO>> queryToDoTasks(@RequestHeader(value = Keys.USERNO) String userNo, WfOrderQueryDTO wfOrderQueryDTO) {
        wfOrderQueryDTO.setUserNo(userNo);
        log.info("查询我的任务,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        if (StringUtils.isBlank(wfOrderQueryDTO.getUserNo())) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        if (StringUtils.isNotEmpty(wfOrderQueryDTO.getAppId())) {
            List<String> list = userService.personRoles(wfOrderQueryDTO.getUserNo(), wfOrderQueryDTO.getAppId());
            log.info("用户对应的角色信息,请求参数:{}", list);
            wfOrderQueryDTO.setRoleCode(list);
        } else {
            List<String> roleCodes = userService.getPersonAllEnableRoles(userNo);
            wfOrderQueryDTO.setRoleCode(roleCodes);
        }
        if (wfOrderQueryDTO.getOrderStatus() != null) {
            if (OrderStatus.PROCESSED.getCode().equals(wfOrderQueryDTO.getOrderStatus())) {
                log.info("查询我的任务已办工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
                BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = queryDoneTasks(userNo, wfOrderQueryDTO);
                return pageInfoResponseBaseResult;
            } else if (OrderStatus.PROCESSING.getCode().equals(wfOrderQueryDTO.getOrderStatus())) {
                log.info("查询我的任务待办工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
                BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = toDoTasks(wfOrderQueryDTO);
                return pageInfoResponseBaseResult;
            }
        }
        log.info("查询我的任务所有工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.myAllTask(wfOrderQueryDTO);
        List<WfOrderResultDTO> wfOrderResultDTOS = setTotalTime(pageInfo);
        pageInfo.setList(wfOrderResultDTOS);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询我的任务所有工单,响应结果:{}", pageInfoResponseBaseResult);
        return pageInfoResponseBaseResult;
    }

    /**
     * 查询已办工单
     *
     * @param userNo 登入用户
     * @return 工单列表
     */
    @GetMapping(value = "/queryDoneTasks")
    @ApiOperation(value = "查询已办工单")
    public BaseResult<PageInfoResponse<WfOrderResultDTO>> queryDoneTasks(@RequestHeader(value = Keys.USERNO) String userNo, WfOrderQueryDTO wfOrderQueryDTO) {
        wfOrderQueryDTO.setUserNo(userNo);
        log.info("查询已办工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        if (StringUtils.isBlank(wfOrderQueryDTO.getUserNo())) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        return doneTasksExtraction(wfOrderQueryDTO);
    }

    @GetMapping(value = "/myApplicationOrder")
    @ApiOperation(value = "我申请的工单")
    public BaseResult<PageInfoResponse<WfOrderResultDTO>> myApplication(@RequestHeader(value = Keys.USERNO) String userNo, WfOrderQueryDTO wfOrderQueryDTO) {
        wfOrderQueryDTO.setUserNo(userNo);
        log.info("查询我申请的工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        if (StringUtils.isBlank(wfOrderQueryDTO.getUserNo())) {
            throw new APIException(APICode.DATA_ERROR, "用户编码不能为空！");
        }
        if (wfOrderQueryDTO.getOrderStatus() != null) {
            if (OrderStatus.PROCESSED.getCode().equals(wfOrderQueryDTO.getOrderStatus())) {
                log.info("查询我申请的已办工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
                return myApplicationDoneOrderExtraction(wfOrderQueryDTO);
            } else if (OrderStatus.PROCESSING.getCode().equals(wfOrderQueryDTO.getOrderStatus())) {
                log.info("查询我申请的待办工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
                return myApplicationToDoOrderExtraction(wfOrderQueryDTO);
            } else if (OrderStatus.REJECT.getCode().equals(wfOrderQueryDTO.getOrderStatus())) {
                log.info("查询我申请的等待消息工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
                return myApplicationRejectOrderExtraction(wfOrderQueryDTO);
            }
        }
        log.info("查询我申请的所有工单,请求参数:{}", JSON.toJSONString(wfOrderQueryDTO));
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.myApplicationAllTask(wfOrderQueryDTO);
        setClerkName(pageInfo);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询我申请的所有工单,响应结果:{}", pageInfoResponseBaseResult);
        return pageInfoResponseBaseResult;
    }


    /**
     * 我申请的工单待办数据抽取
     */
    private BaseResult<PageInfoResponse<WfOrderResultDTO>> myApplicationToDoOrderExtraction(WfOrderQueryDTO wfOrderQueryDTO) {
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.myApplicationToDoOrder(wfOrderQueryDTO);
        setClerkName(pageInfo);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询我申请的工单,响应结果:{}", pageInfoResponseBaseResult);
        return pageInfoResponseBaseResult;
    }

    /**
     * 我申请的工单驳回数据抽取
     */
    private BaseResult<PageInfoResponse<WfOrderResultDTO>> myApplicationRejectOrderExtraction(WfOrderQueryDTO wfOrderQueryDTO) {
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.myApplicationRejectOrder(wfOrderQueryDTO);
        setClerkName(pageInfo);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询我申请的工单,响应结果:{}", pageInfoResponseBaseResult);
        return pageInfoResponseBaseResult;
    }

    private PageInfo<WfOrderResultDTO> setClerkName(PageInfo<WfOrderResultDTO> pageInfo) {
        List<WfOrderResultDTO> list = pageInfo.getList();
        if (CollectionUtils.isNotEmpty(list)) {
            for (WfOrderResultDTO wfOrderResultDTO : list) {
                if (Constants.STATUS_0.equals(wfOrderResultDTO.getType()) && wfOrderResultDTO.getCurrentNode().contains(FlowConstant.COUNTERSIGN_NAME)) {
                    wfOrderResultDTO.setName(wfOrderResultDTO.getName() + FlowConstant.COUNTERSIGN_NAME);
                }
            }
        }
        pageInfo.setList(list);
        return pageInfo;
    }

    /**
     * 我申请的工单已办数据抽取
     */
    private BaseResult<PageInfoResponse<WfOrderResultDTO>> myApplicationDoneOrderExtraction(WfOrderQueryDTO wfOrderQueryDTO) {
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.myApplicationDoneOrder(wfOrderQueryDTO);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询我申请的工单,响应结果:{}", pageInfoResponseBaseResult);
        return pageInfoResponseBaseResult;
    }

    /**
     * 待办数据抽取
     */
    private BaseResult<PageInfoResponse<WfOrderResultDTO>> toDoTasksExtraction(WfOrderQueryDTO wfOrderQueryDTO) {
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.queryToDoTasks(wfOrderQueryDTO);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询待办工单,响应结果:{}", pageInfoResponseBaseResult);
        return pageInfoResponseBaseResult;
    }

    /**
     * 待办数据抽取2.0
     */
    private BaseResult<PageInfoResponse<WfOrderResultDTO>> toDoTasks(WfOrderQueryDTO wfOrderQueryDTO) {
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.toDoTasks(wfOrderQueryDTO);
        List<WfOrderResultDTO> wfOrderResultDTOS = setTotalTime(pageInfo);
        pageInfo.setList(wfOrderResultDTOS);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询待办工单,响应结果:{}", pageInfoResponseBaseResult);
        return pageInfoResponseBaseResult;
    }

    /**
     * 已办数据抽取
     */
    private BaseResult<PageInfoResponse<WfOrderResultDTO>> doneTasksExtraction(WfOrderQueryDTO wfOrderQueryDTO) {
        PageInfo<WfOrderResultDTO> pageInfo = wfProcessQueryService.queryDoneTasks(wfOrderQueryDTO);
        List<WfOrderResultDTO> wfOrderResultDTOS = setTotalTime(pageInfo);
        pageInfo.setList(wfOrderResultDTOS);
        BaseResult<PageInfoResponse<WfOrderResultDTO>> pageInfoResponseBaseResult = setPageResult(pageInfo);
        log.info("查询已办工单,响应结果:{}", JSON.toJSONString(pageInfoResponseBaseResult));
        return pageInfoResponseBaseResult;
    }

    /**
     * @description : 给查询的结果转换节点耗时
     * @params : [pageInfo]
     * @returns : java.util.List<com.glp.work.flow.response.WfOrderResultDTO>
     * @author : 郭永伟
     * @date : 2020/11/4
     */
    public static List<WfOrderResultDTO> setTotalTime(PageInfo<WfOrderResultDTO> pageInfo) {
        log.info("给查询的结果转换节点耗时");
        List<WfOrderResultDTO> list = pageInfo.getList();
        if (CollectionUtils.isNotEmpty(list)) {
            for (WfOrderResultDTO wfOrderResultDTO : list) {
                wfOrderResultDTO.setTotalTime(DateUtil.getDistanceTime(Integer.parseInt(wfOrderResultDTO.getTotalTime()) * 1000L));
                wfOrderResultDTO.setVersion(VersionUtils.getVersion(wfOrderResultDTO.getVersion()));
            }
        }
        return list;
    }

    /**
     * @description : 设置分页
     * @params : [pageInfo]
     * @returns : com.glp.common.reponse.BaseResult<com.glp.work.flow.response.PageInfoResponse<com.glp.work.flow.response.WfOrderResultDTO>>
     * @author : 郭永伟
     * @date : 2020/9/25
     */
    public static BaseResult<PageInfoResponse<WfOrderResultDTO>> setPageResult(PageInfo pageInfo) {
        PageInfoResponse<WfOrderResultDTO> response = new PageInfoResponse<>();
        response.setPageNum(pageInfo.getPageNum());
        response.setPageSize(pageInfo.getPageSize());
        response.setSize(pageInfo.getPages());
        response.setTotal(pageInfo.getTotal());
        response.setList(pageInfo.getList());
        return new BaseResult<>(ReturnEnum.SUCCESS.getCode(), ReturnEnum.SUCCESS.getMessage() + TraceIDUtils.getLogTraceId(), response);
    }

    @ApiOperation(value = "查询工单详情")
    @PostMapping(value = "/queryOrderDetail")
    public BaseResult<WfOrderResponse> queryOrderDetail(@RequestBody WfOrderDetailQueryDTO wfOrderDetailQueryDTO) {
        log.info("查询工单详情,请求参数:{},{}", JSON.toJSONString(wfOrderDetailQueryDTO));
        WfOrderResponse wfOrder = wfProcessQueryService.queryOrderDetail(wfOrderDetailQueryDTO.getUserNo(), wfOrderDetailQueryDTO);
        BaseResult<WfOrderResponse> result = new BaseResult<>(APICode.SUCCESS.getCode(), "查询工单详情结果" + TraceIDUtils.getLogTraceId(), wfOrder);
        log.info("查询工单详情,响应结果:{}", JSON.toJSONString(result));
        return result;
    }

    @ApiOperation(value = "领取任务，查看工单详情")
    @PostMapping(value = "/claimTask")
    public BaseResult<WfOrderResponse> claimTask(@RequestHeader(value = Keys.USERNO) String userNo, @RequestBody WfOrderDetailQueryDTO wfOrderDetailQueryDTO) {
        wfOrderDetailQueryDTO.setUserNo(userNo);
        log.info("查询工单详情,请求参数:{}", JSON.toJSONString(wfOrderDetailQueryDTO));
        try {
            Task task = taskService.createTaskQuery().taskId(wfOrderDetailQueryDTO.getTaskId()).singleResult();
            if (task != null) {
                String assignee = task.getAssignee();
                if (assignee == null) {
                    log.info("领取任务：{}", wfOrderDetailQueryDTO);
                    taskService.claim(wfOrderDetailQueryDTO.getTaskId(), wfOrderDetailQueryDTO.getUserNo());
                    syncProcessStatusService.claimSendEmailMq(userNo, wfOrderDetailQueryDTO);
                }
            } else {
                log.error("当前任务不存在,或已被完成！{}", wfOrderDetailQueryDTO);
                throw new APIException(APICode.DATA_ERROR, "当前任务不存在，或已被完成！taskId：" + wfOrderDetailQueryDTO.getTaskId());
            }
        } catch (FlowableObjectNotFoundException e) {
            log.error("当前任务不存在！{}", wfOrderDetailQueryDTO);
            throw new APIException(APICode.DATA_ERROR, "当前任务不存在！taskId：" + wfOrderDetailQueryDTO.getTaskId());
        } catch (FlowableTaskAlreadyClaimedException e) {
            log.error("当前任务已被领取！：{}", wfOrderDetailQueryDTO);
            throw new APIException(APICode.DATA_ERROR, "当前任务已被领取！taskId：" + wfOrderDetailQueryDTO.getTaskId());
        }


        BaseResult<WfOrderResponse> wfOrderResponseBaseResult = queryOrderDetail(wfOrderDetailQueryDTO);
        log.info("查询工单详情,响应结果:{}", JSON.toJSONString(wfOrderResponseBaseResult));
        return wfOrderResponseBaseResult;
    }


    @ApiOperation(value = "根据TaskID查询待办工单详情 Feign")
    @PostMapping(value = "/client/queryOrderDetail/todo")
    @ResponseBody
    @Override
    public BaseResult<WfOrderResponse> queryToDoOrderDetail(@RequestBody WfOrderDetailQueryToDoDTO wfOrderDetailQueryToDoDTO) {
        log.info("根据TaskID查询待办工单详情 Feign,请求参数:{},{}", wfOrderDetailQueryToDoDTO);
        if (StringUtils.isBlank(wfOrderDetailQueryToDoDTO.getTaskId())) {
            throw new APIException(APICode.DATA_ERROR, "任务ID不能为空！");
        }
        WfOrderDetailQueryDTO wfOrderDetailQueryDTO = new WfOrderDetailQueryDTO();
        wfOrderDetailQueryDTO.setTaskId(wfOrderDetailQueryToDoDTO.getTaskId());
        BaseResult<WfOrderResponse> wfOrderResponseBaseResult = queryOrderDetail(wfOrderDetailQueryDTO);
        log.info("根据TaskID查询待办工单详情 Feign,响应结果:{}", JSON.toJSONString(wfOrderResponseBaseResult));
        return wfOrderResponseBaseResult;

    }

    @ApiOperation(value = "查询代办工单详情 2.0 (领取任务)")
    @PostMapping(value = "/client/queryOrderDetail/claimTask")
    @ResponseBody
    @Override
    public BaseResult<WfOrderResponse> queryOrderDetailClaimTask(@RequestBody WfOrderDetailQueryDTO wfOrderDetailQueryDTO) {
        log.info("根据TaskID查询待办工单详情 Feign,请求参数:{},{}", wfOrderDetailQueryDTO);
        if (StringUtils.isBlank(wfOrderDetailQueryDTO.getTaskId())) {
            throw new APIException(APICode.DATA_ERROR, "任务ID不能为空！");
        }
        wfOrderDetailQueryDTO.setTaskId(wfOrderDetailQueryDTO.getTaskId());
        BaseResult<WfOrderResponse> wfOrderResponseBaseResult = claimTask(wfOrderDetailQueryDTO.getUserNo(), wfOrderDetailQueryDTO);
        log.info("根据TaskID查询待办工单详情 Feign,响应结果:{}", JSON.toJSONString(wfOrderResponseBaseResult));
        return wfOrderResponseBaseResult;
    }

    @ApiOperation(value = "根据processId查询已办工单详情 Feign")
    @PostMapping(value = "/client/queryOrderDetail/done")
    @ResponseBody
    @Override
    public BaseResult<WfOrderResponse> queryDoneOrderDetail(@RequestBody WfOrderDetailQueryDoneDTO wfOrderDetailQueryDoneDTO) {
        log.info("根据processId查询已办工单详情 Feign,请求参数:{},{}", wfOrderDetailQueryDoneDTO);
        if (StringUtils.isBlank(wfOrderDetailQueryDoneDTO.getProcessId())) {
            throw new APIException(APICode.DATA_ERROR, "流程实例ID不能为空！");
        }
        WfOrderDetailQueryDTO wfOrderDetailQueryDTO = new WfOrderDetailQueryDTO();
        wfOrderDetailQueryDTO.setProcessId(wfOrderDetailQueryDoneDTO.getProcessId());
        wfOrderDetailQueryDTO.setShowLevel(wfOrderDetailQueryDoneDTO.getShowLevel());
        BaseResult<WfOrderResponse> wfOrderResponseBaseResult = queryOrderDetail(wfOrderDetailQueryDTO);
        log.info("根据processId查询已办工单详情 Feign,响应结果:{}", JSON.toJSONString(wfOrderResponseBaseResult));
        return wfOrderResponseBaseResult;
    }

    @ApiOperation(value = "查询工单详情")
    @PostMapping(value = "/client/queryOrderDetail")
    @ResponseBody
    @Override
    public BaseResult<WfOrderResponse> queryOrderDetail(@RequestBody WfOrderDetailQueryDoneDTO wfOrderDetailQueryDoneDTO) {
        log.info("查询工单详情,请求参数:{},{}", wfOrderDetailQueryDoneDTO);
        if (StringUtils.isBlank(wfOrderDetailQueryDoneDTO.getProcessId())) {
            throw new APIException(APICode.DATA_ERROR, "流程实例ID不能为空！");
        }
        if (StringUtils.isBlank(wfOrderDetailQueryDoneDTO.getUserNo())) {
            throw new APIException(APICode.DATA_ERROR, "userNo不能为空！");
        }
        WfOrderDetailQueryDTO wfOrderDetailQueryDT = new WfOrderDetailQueryDTO();
        wfOrderDetailQueryDT.setProcessId(wfOrderDetailQueryDoneDTO.getProcessId());
        wfOrderDetailQueryDT.setUserNo(wfOrderDetailQueryDoneDTO.getUserNo());
        wfOrderDetailQueryDT.setShowLevel(wfOrderDetailQueryDoneDTO.getShowLevel());
        BaseResult<WfOrderResponse> wfOrderResponseBaseResult = queryOrderDetail(wfOrderDetailQueryDT);
        return wfOrderResponseBaseResult;
    }


    @ApiOperation(value = "审批历史查询接口")
    @GetMapping(value = "/queryHistory/{orderId}")
    @ResponseBody
    @Override
    public BaseResult<List<FlowTaskHistoryDTO>> queryHistory(@PathVariable String orderId,
                                                             @RequestParam(name = "appId") String appId) {
        log.info("审批历史查询接口,请求参数:{},{}", orderId, appId);
        List<FlowTaskHistoryDTO> wfCommentResponses = wfProcessQueryService.queryHistory(orderId, appId);
        BaseResult<List<FlowTaskHistoryDTO>> result = new BaseResult<>(APICode.SUCCESS.getCode(), "审批历史查询接口" + TraceIDUtils.getLogTraceId(), wfCommentResponses);
        log.info("审批历史查询接口,响应结果:{}", JSON.toJSONString(result));
        return result;
    }

    @ApiOperation(value = "查询表单快照")
    @PostMapping(value = "/queryFormSnapshot")
    @ResponseBody
    public BaseResult<WfFormExample> queryFormSnapshot(@RequestBody WfOrderDetailQueryDTO wfOrderDetailQueryDTO) {
        log.info("查询表单快照,请求参数:{}", wfOrderDetailQueryDTO);
        if (StringUtils.isBlank(wfOrderDetailQueryDTO.getProcessId())) {
            throw new APIException(APICode.DATA_ERROR, "流程实例ID不能为空！");
        }
        if (StringUtils.isBlank(wfOrderDetailQueryDTO.getTaskId())) {
            throw new APIException(APICode.DATA_ERROR, "taskId不能为空！");
        }
        WfFormExample wfFormExample = wfFormSnapshotService.queryFormSnapshot(wfOrderDetailQueryDTO);
        BaseResult<WfFormExample> result = new BaseResult<>(APICode.SUCCESS.getCode(), "查询表单快照" + TraceIDUtils.getLogTraceId(), wfFormExample);
        log.info("查询表单快照,响应结果:{}", JSON.toJSONString(result));
        return result;
    }


    @Override
    @ApiOperation(value = "可驳回历史节点查询")
    @GetMapping(value = "/client/queryHistory")
    @ResponseBody
    public BaseResult<List<FlowTaskHistoryDTO>> queryHistoryUserTask(
            @RequestParam(name = "taskId") String taskId,
            @RequestParam(name = "processId") String processId) {
        log.info("可驳回历史节点查询,请求参数:{}", processId);
        List<FlowTaskHistoryDTO> wfCommentResponses = wfProcessQueryService.queryHistoryUserTask(processId, taskId);
        BaseResult<List<FlowTaskHistoryDTO>> result = new BaseResult<>(APICode.SUCCESS.getCode(), "可驳回历史节点查询" + TraceIDUtils.getLogTraceId(), wfCommentResponses);
        log.info("可驳回历史节点查询,响应结果:{}", JSON.toJSONString(result));
        return result;
    }

    @ApiOperation(value = "可驳回节点查询")
    @GetMapping(value = "/client/queryRejectTask")
    @ResponseBody
    public BaseResult<List<WfTaskAssignNode>> queryRejectTask(
            @RequestParam(name = "taskId") String taskId) {
        log.info("可驳回节点查询,请求参数:{}", taskId);
        List<WfTaskAssignNode> wfCommentResponses = wfProcessQueryService.queryRejectTask(taskId);
        BaseResult<List<WfTaskAssignNode>> result = new BaseResult<>(APICode.SUCCESS.getCode(), "可驳回节点查询" + TraceIDUtils.getLogTraceId(), wfCommentResponses);
        log.info("可驳回节点查询,响应结果:{}", JSON.toJSONString(result));
        return result;
    }


    @Override
    @ApiOperation(value = "查询批量审批工单")
    @PostMapping(value = "/client/getBatchOrder")
    @ResponseBody
    public BaseResult<BatchOrder> getBatchOrder(@RequestHeader String userNo, @RequestBody List<String> processesIds) {
        log.info("查询批量审批工单,请求参数:{}", processesIds);
        BatchOrder batchOrder = wfBatchService.getBatchOrder(processesIds, userNo);
        return new BaseResult<>(APICode.SUCCESS.getCode(), "查询批量审批工单" + TraceIDUtils.getLogTraceId(), batchOrder);
    }


    @ApiOperation(value = "查询所有已启用的流程")
    @GetMapping(value = "/client/getKeyList")
    @ResponseBody
    @Override
    public BaseResult<List<ProcessResponse>> getKeyList(@RequestParam(value = "appId") String appId) {
        log.info("查询所有已启用的流程信息:{}", appId);
        List<ProcessResponse> list = wfPlatformDefModleService.getKeyList(appId);
        return new BaseResult<>(APICode.SUCCESS.getCode(), "查询所有已启用的流程信息" + TraceIDUtils.getLogTraceId(), list);
    }

    @ApiOperation(value = "记录表单耗时")
    @PostMapping(value = "/consumingForms")
    @ResponseBody
    public void consumingForms(@RequestParam String taskId, @RequestParam int time) {
        log.info("记录表单耗时,请求参数:{}", taskId);
        WfFormTimeConsuming wfFormTimeConsuming = new WfFormTimeConsuming();
        wfFormTimeConsuming.setTaskTd(taskId);
        wfFormTimeConsuming = wfFormTimeConsumingMapper.selectOne(wfFormTimeConsuming);
        if (wfFormTimeConsuming != null) {
            Example example = new Example(WfFormTimeConsuming.class);
            example.createCriteria().andEqualTo("taskTd", taskId);
            wfFormTimeConsuming.setTimeConsuming(wfFormTimeConsuming.getTimeConsuming() + time);
            wfFormTimeConsumingMapper.updateByExampleSelective(wfFormTimeConsuming, example);
        } else {
            wfFormTimeConsuming = new WfFormTimeConsuming();
            wfFormTimeConsuming.setTaskTd(taskId);
            wfFormTimeConsuming.setTimeConsuming(time);
            wfFormTimeConsumingMapper.insertSelective(wfFormTimeConsuming);
        }
    }

    @ApiOperation(value = "查询工单详情")
    @PostMapping(value = "/client/sa/queryOrderDetail")
    @ResponseBody
	@Override
	public BaseResult<WfOrderResponse> queryOrderDetailBySa(@RequestBody WfOrderDetailQueryBySaDTO wfOrderDetailQueryDTO) {
       log.info("查询工单详情,请求参数:{},{}", JSON.toJSONString(wfOrderDetailQueryDTO));
       WfOrderResponse wfOrder = wfProcessQueryService.queryOrderDetailBySa(wfOrderDetailQueryDTO);
       BaseResult<WfOrderResponse> result = new BaseResult<>(APICode.SUCCESS.getCode(), "查询工单详情结果" + TraceIDUtils.getLogTraceId(), wfOrder);
       log.info("查询工单详情,响应结果:{}", JSON.toJSONString(result));
       return result;
	}
    

    
}